package xyz.zhno.project.commons.sentinel.exception;

import cn.hutool.core.date.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import xyz.zhno.project.commons.core.dto.ResultError;
import xyz.zhno.project.commons.core.exception.ProjectException;
import xyz.zhno.project.commons.core.exception.ProjectExceptionCodeEnum;

/**
 * 全局异常处理
 * @author zh_o
 * @date 2020-10-31
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 自定义异常处理
     * @param e 自定义异常
     * @return 响应错误结果集
     */
    @ExceptionHandler(ProjectException.class)
    public ResponseEntity<ResultError> errorHandler(ProjectException e) {
        log.error("Exception: {}, Code: {}, Message: {}, Time: {}, StackTrace: [{}]", e.getClass(), e.getCode(), e.getMessage(), DateUtil.now(), getStackTrace(e));
        return new ResponseEntity<>(ResultError.builder()
                .code(e.getCode())
                .message(e.getMessage())
                .build(),
                HttpStatus.INTERNAL_SERVER_ERROR);
    }

    /**
     * 异常处理
     * @param e 异常
     * @return 响应错误结果集
     */
    @ExceptionHandler(Exception.class)
    public ResponseEntity<ResultError> errorHandler(Exception e) {
        log.error("Exception: {}, Message: {}, Time: {} " + "\r\n" + " StackTrace: [{}]", e.getClass(), e.getMessage(), DateUtil.now(), getStackTrace(e));
        return new ResponseEntity<>(ResultError.builder()
                .code(ProjectExceptionCodeEnum.SYS_ERROR.getCode())
                .message(ProjectExceptionCodeEnum.SYS_ERROR.getMessage())
                .build(),
                HttpStatus.INTERNAL_SERVER_ERROR);
    }


    /**
     * 获取堆栈信息流
     * @param e 传入异常
     * @return 拼接后的堆栈信息流
     */
    private String getStackTrace(Exception e) {
        StringBuilder builder = new StringBuilder();
        for (StackTraceElement st : e.getStackTrace()) {
            builder.append(st.toString()).append("\r\n");
        }
        return builder.toString();
    }

}
